#ifndef LIST_H
#define LIST_H

#include <Types.h>

#define get_obj(linkaddr, objtype, linkname) \
	((objtype *)((uint8 *)(linkaddr) - (uint8 *)&((objtype *)(0x10))->linkname + 0x10))


enum direction{AFTER, BEFOR};

struct Link{
	Link *next;
	Link *prev;
};

class List{
	Link head;
	uint32 sz;
	public:
		List();
		void init();
		inline const Link * getCHead() const;
		Link * getHead();
		void insert(Link *obj, direction drt, Link *pred_obj);
		inline void insAfter(Link *obj, Link *after_obj);
		inline void insBefor(Link *obj, Link *befor_obj);
		void insBegin(Link *obj);
		void insEnd(Link *obj);
		void push(Link *obj);
		Link * remove(Link *obj);
		inline bool isEmpty() const;
		Link * pop();
		inline Link * getFirst() const;
		inline uint32 getSize() const;
};



inline const Link * List::getCHead() const{
	return &head;
}

inline bool List::isEmpty() const{
	if(&head == head.next) return true;
	return false;
}

inline Link * List::getFirst() const{
	if(!isEmpty()){
		return head.next;
	}
	return 0;
}


inline void List::insAfter(Link *obj, Link *after_obj){
	insert(obj, AFTER, after_obj);
}

inline void List::insBefor(Link *obj, Link *befor_obj){
	insert(obj, BEFOR, befor_obj);
}

inline uint32 List::getSize() const{
	return sz;
}


#endif /* LIST_H */
